﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ZedGraph;

namespace UI
{
    public partial class FrmSiteOutput : Form
    {
        Dictionary<string, IColorScheme> color_schemes = new Dictionary<string, IColorScheme>();

        public FrmSiteOutput(string Label)
        {
            InitializeComponent();

            this.Text = Label;
            this.timer1.Interval = 100;
            this.timer1.Start();
        }

        public static bool Contains(string FindInString, string FindString)
        {
            if (System.Globalization.CultureInfo.InvariantCulture.CompareInfo.IndexOf(FindInString, FindString, System.Globalization.CompareOptions.IgnoreCase) >= 0)
            {
                return true;
            }
            return false;
        }
        
        public void ClearGraphs()
        {
            tabControl1.Controls.Clear();
        }
        public static string[] GetMapLabels(string FileName)
        {
            if (System.IO.Path.GetFileNameWithoutExtension(FileName).Contains("Cohort_"))
            {
                return new string[]{"CohortData"};
            }
            else if ((System.IO.Path.GetFileNameWithoutExtension(FileName).Contains("Site")))
            {
                return new string[] { "SiteData", "CohortData" };  //,
            }
            else if ((System.IO.Path.GetExtension(FileName) == ".txt"))
            {
                return new string[] { System.IO.Path.GetFileName(FileName)};
            }
            else if ((System.IO.Path.GetFileNameWithoutExtension(FileName).Contains("Establishment")))
            {
                return null;
            }
            return null;
        }
        static string[] GetTabLabels(string FileName, string Header)
        {
            if (System.IO.Path.GetFileNameWithoutExtension(FileName).Contains("Cohort_"))
            {
                return new string[] { Header };
            }
            else if ((System.IO.Path.GetFileNameWithoutExtension(FileName).Contains("Site")))
            {
                string[] directories = FileName.Split(System.IO.Path.DirectorySeparatorChar);
                string SiteLocation = directories[directories.Length - 2];

                return new string[] { Header, Header + SiteLocation };
            }
            else if (System.IO.Path.GetExtension(FileName) == ".txt")
            {
                string[] directories = FileName.Split(System.IO.Path.DirectorySeparatorChar);
                string SiteLocation = directories[directories.Length - 2];

                return new string[] { Header };
            }
            else return null;
        }
        static string GetDataLabel(string FileName, string Header)
        {
            if (System.IO.Path.GetFileNameWithoutExtension(FileName).Contains("Cohort_"))
            {
                string FileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(FileName);

                string Year = FileNameWithoutExtension.Split('_')[2];
                string Species = FileNameWithoutExtension.Split('_')[1];

                return Species + Year;
            }
            else if ((System.IO.Path.GetFileNameWithoutExtension(FileName).Contains("Site")))
            {
                string[] directories = FileName.Split(System.IO.Path.DirectorySeparatorChar);
                string SiteLocation = directories[directories.Length - 2];

                return directories[directories.Length - 2];
            }
            else if ((System.IO.Path.GetExtension(FileName) == ".txt"))
            {
                 
                return FileName;
                
                 
            }
            else
            {
                return null;
            }
        }

        public class CurveParameters
        {
            public double[] X { get; private set; }
            public double[] TimeSeries { get; private set; }
            public string TabLabel { get; private set; }
            public string DataLabel { get; private set; }

            public CurveParameters(double[] _X, double[] _TimeSeries, string _TabLabel, string _DataLabel)
            {
                X = _X;
                TimeSeries = _TimeSeries;
                TabLabel = _TabLabel;
                DataLabel = _DataLabel;
            }
        }
        List<CurveParameters> MyCurveParameters = new List<CurveParameters>();

        public void AddCurve(double[] X, double[] TimeSeries, string File, string Header)
        {
            string DataLabel = GetDataLabel(File, Header);

            // Can be two tablabels if curve should be in both cohortdata and sitedata
            string[] TabLabel = GetTabLabels(File, Header);

            MyCurveParameters.Add(new CurveParameters(X, TimeSeries, TabLabel[0], DataLabel));
        }
        void AllowExportData(object o, EventArgs e)
        {
            double t = 0.0;
        }
        void UpdateCurves()
        {

            if (MyCurveParameters.Count() == 0) return;


            if (MyCurveParameters[0].TimeSeries.Length == 0) return;

            ZedGraphControl Graph = null;

            ZedGraph.PointPairList Series = new PointPairList(MyCurveParameters[0].X, MyCurveParameters[0].TimeSeries);

            System.Windows.Forms.TabPage MyTabPage = null;

            foreach (System.Windows.Forms.TabPage control in this.tabControl1.Controls)
            {
                if (control.Text == MyCurveParameters[0].TabLabel)
                {
                    MyTabPage = control;
                }
            }

            if (MyTabPage == null)
            {
                MyTabPage = new TabPage();

                MyTabPage.Text = MyCurveParameters[0].TabLabel;

                Graph = new ZedGraphControl();

                color_schemes.Add(MyCurveParameters[0].TabLabel, new ColorScheme(ColorScheme.DefaultColorValues));

                Graph.GraphPane.XAxis.Title.Text = "Time";
                Graph.GraphPane.YAxis.Title.Text = "";
                Graph.GraphPane.Title.Text = "";
                Graph.Dock = System.Windows.Forms.DockStyle.Fill;
                
                Graph.GraphPane.XAxis.Scale.Min = double.MaxValue;
                Graph.GraphPane.XAxis.Scale.Max = double.MinValue;

                Graph.GraphPane.YAxis.Scale.Min = double.MaxValue;
                Graph.GraphPane.YAxis.Scale.Max = double.MinValue;

                MyTabPage.Controls.Add(Graph);

                //MyTabPage.Show();

                tabControl1.TabPages.Add(MyTabPage);
            }

            IColorScheme color_scheme = color_schemes[MyTabPage.Text];

            System.Drawing.Color color = color_scheme.NextColor;

            foreach (System.Windows.Forms.Control control in MyTabPage.Controls)
            {
                if (control.GetType() == typeof(ZedGraph.ZedGraphControl))
                {
                    Graph = (ZedGraphControl)control;

                    
                   
                    Graph.MouseClick += AllowExportData;

                    Graph.GraphPane.XAxis.Scale.Max = Math.Max(Graph.GraphPane.XAxis.Scale.Max, Max_Axis(MyCurveParameters[0].X.Max()));
                    Graph.GraphPane.XAxis.Scale.Min = Math.Min(Graph.GraphPane.XAxis.Scale.Min, Min_Axis(MyCurveParameters[0].X.Min()));
                    Graph.GraphPane.XAxis.Scale.MajorStep = (Graph.GraphPane.XAxis.Scale.Max - Graph.GraphPane.XAxis.Scale.Min) / 10;
                    Graph.GraphPane.XAxis.Scale.MinorStep = Graph.GraphPane.XAxis.Scale.MajorStep;

                    Graph.GraphPane.YAxis.Scale.Max = Math.Max(Graph.GraphPane.YAxis.Scale.Max, Max_Axis(MyCurveParameters[0].TimeSeries.Max()));
                    Graph.GraphPane.YAxis.Scale.Min = Math.Min(Graph.GraphPane.YAxis.Scale.Min, Min_Axis(MyCurveParameters[0].TimeSeries.Min()));
                    Graph.GraphPane.YAxis.Scale.MajorStep = (Graph.GraphPane.YAxis.Scale.Max - Graph.GraphPane.YAxis.Scale.Min) / 10;
                    Graph.GraphPane.YAxis.Scale.MinorStep = Graph.GraphPane.YAxis.Scale.MajorStep;

                    for (int c = Graph.GraphPane.CurveList.Count() - 1; c >= 0; c--)
                    {
                        if (Graph.GraphPane.CurveList[c].Label.Text == MyCurveParameters[0].DataLabel)
                        {
                            Graph.GraphPane.CurveList.RemoveAt(c);
                        }
                    }

                    LineItem curve = Graph.GraphPane.AddCurve(MyCurveParameters[0].DataLabel, Series, color, SymbolType.None);

                    Graphics grfx = Graphics.FromImage(new Bitmap(1, 1));
                    
                    float FontSize= Graph.GraphPane.Legend.FontSpec.Size;

                    while(grfx.MeasureString(MyCurveParameters[0].DataLabel, Graph.GraphPane.Legend.FontSpec.GetFont(1) , new PointF(0,0), new StringFormat( StringFormatFlags.MeasureTrailingSpaces )).Width > Graph.GraphPane.Rect.Width)
                    {
                        Graph.GraphPane.Legend.FontSpec.Size *= 0.99F;
                    }

                    curve.Line.Width = 2;

                }   
            }

            Graph.Invalidate();
            Graph.Update();
            Graph.Refresh();
             

            MyCurveParameters.RemoveAt(0); 
        }
        double Max_Axis(double max_value)
        {
            return max_value + 0.05F * Math.Abs(max_value);
        }
        double Min_Axis(double min_value)
        {
            return min_value - 0.05F * Math.Abs(min_value);
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            UpdateCurves();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (backgroundWorker1.IsBusy ==false)
            {
                this.backgroundWorker1.RunWorkerAsync();
            }
        }
    }
}
